﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>Multi Tenancy</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
	</head>

	<body>

		<div class="document-contents">

			<h3>What Is Multi Tenancy?</h3>
			<p>
				<a href="https://en.wikipedia.org/wiki/Multitenancy">Wikipedia</a>: "Software 
				<strong>Multitenancy</strong> refers to a software <strong>architecture</strong> in which a 
				<strong>single instance</strong> of a software runs on a server and serves 
				<strong>multiple tenants</strong>. 
A tenant is a group of users who share a common access with specific privileges 
to the software instance. With a multitenant architecture, a software application 
is designed to provide every tenant a <strong>dedicated share of the instance including 
its data</strong>, configuration, user management, tenant individual functionality and
 non-functional properties. Multitenancy contrasts with multi-instance architectures,
  where separate software instances operate on behalf of different tenants"</p>
			<p>Multi-tenancy is used to create <strong>SaaS</strong> (Software as-a Service) 
applications (cloud computing). There are some types of multi-tenancy:</p>
			<h4>Multiple Deployment - Multiple Database</h4>
			<p>This is <strong>not multi tenancy</strong> actually. But, if we run <strong>one instance</strong> of 
the application <strong>for each</strong> customer (tenant) with a <strong>
seperated database</strong>, we can serve 
to <strong>multiple tenants</strong> in a single server. We just make sure that multiple instance 
of the application don't <strong>conflict</strong> with each other in same 
server environment.</p>
			<p>This can be possible also for an <strong>existing application</strong> which is not designed 
multitenant. It's easier to create such an application since the application is 
not aware of multitenancy. But there are setup, utilization and maintenance 
problems in this approach.</p>
			<h4>Single Deployment - Multiple Database</h4>
			<p>ln this approach, we may run a <strong>single instance</strong> of the application in a 
server. For each user login, we check tenant of the user from a <strong>master database</strong> 
and get database informations (<strong>connection string</strong>) of the tenant. Then we can 
store connection string into a <strong>session-like</strong> variable and perform all database 
operations using this <strong>tenant-specific</strong> connection string.</p>
			<p>In this approach, application should be designed as multi-tenant in some 
level. But most of the application can remain independed from multi-tenancy. 
This approach is also some setup, utilization and maintenance problems. We 
should create and maintain a <strong>seperated database</strong> for each tenant.</p>
			<h4>Single Deployment - Single Database</h4>
			<p>This is the most <strong>real multi-tenancy</strong> architecture: We only deploy 
				<strong>single 
instance</strong> of the application with a <strong>single database</strong> into a 
				<strong>single server</strong>. We have 
a <strong>TenantId</strong> (or similar) field in each table (for a RDBMS) which 
is used to isolate a tenant's data from others.</p>
			<p>This is easy to setup and maintain. But harder to create such an application. 
Because, we must prevent a Tenant to read or write other tenant datas. We may 
add <strong>TenantId filter</strong> for each database read (select) operation. Also, we may 
check in every write, if this entity is related to the <strong>current tenant</strong>. This is 
tedious and error-prone. But ASP.NET Boilerplate helps us here by using <strong>
automatic data filtering</strong>.</p>
			<p>This approach may have performance problems if we have many tenants with huge 
datas. We may use table partitioning feature of relational databases and/or 
group tenants in different servers.</p>
			<h3>Multi-Tenancy in ASP.NET Boilerplate</h3>
			<p>ASP.NET Boilerplate provides infrastructure to create a <strong>single-deployment, 
single-database, multi-tenant</strong> architecture.</p>
			<h4>Enabling Multi Tenancy</h4>
			<p>Multi-tenancy is disabled by default. We can enable it in PreInitialize 
	of our module as shown below:</p>
			<pre lang="cs">Configuration.MultiTenancy.IsEnabled = true;&nbsp;</pre>
			<h4>Host vs Tenant</h4>
			<p>First, we should define two terms used in a multi-tenant system:</p>
			<ul>
				<li>
					<strong>Tenant</strong>: A customer which have it's own users, roles, 
	permissions, settings... and uses the application completely isolated from 
	other tenants. A multi-tenant application will have one or more tenants. If 
	this is a CRM application, different tenants have also thier own accounts, 
	contacts, products and orders. So, when we say a '<strong>tenant user</strong>', we mean a user owned by a tenant.</li>
				<li>
					<strong>Host</strong>: Host is singleton (there is a single host). The 
	Host is responsible to create and manage tenants. So, a '<strong>host user</strong>' is higher level and independent from all 
	tenants and can control they.</li>
			</ul>
			<h4>Session</h4>
			<p>ASP.NET Boilerplate defines <strong>IAbpSession</strong> interface to obtain 
current <strong>user</strong> and <strong>tenant</strong> ids. This interface is 
used in multi-tenancy to get current tenant's id. Thus, it can filter datas 
based on current tenant's id. We can say these rules: </p>
			<ul>
				<li>If both of UserId and TenantId is null, then current user is <strong>not logged 
	in</strong> to the system. So, we can not know if it's a host user or tenant user. In 
	this case, user can not access to <a href="/Pages/Documents/Authorization">authorized</a> content.</li>
				<li>If UserId is not null and TenantId is null, then we can know that 
	current user is a <strong>host user</strong>.</li>
				<li>If UserId is not null and also TenantId is not null, we can know that 
	current user is a <strong>tenant user</strong>.</li>
			</ul>
			<p>See <a href="/Pages/Documents/Abp-Session">session documentation</a> for more 
information on the session.</p>
			<h4>Data Filters</h4>
			<p>While retrieving <a href="/Pages/Documents/Entities">entities</a> from 
database, we must add a TenantId filter to get only current tenant's entities. 
ASP.NET Boilerplate automatically does it when you implement one of two 
interfaces for your entity: IMustHaveTenant and IMayHaveTenant.</p>
			<h5>IMustHaveTenant Interface</h5>
			<p>This interface is used to distinguish entities of different tenants by 
defining <strong>TenantId</strong> property. An example entitiy that implements IMustHaveTenant:</p>
			<pre lang="cs">public class Product : Entity, <strong>IMustHaveTenant</strong>
{
    <strong>public int TenantId { get; set; }</strong>

    public string Name { get; set; }

    //...other properties
}</pre>
			<p>Thus, ASP.NET Boilerplate knows that this is a tenant-specific entity and 
automatically isolates entities of a tenant from other tenants.</p>
			<h5>IMayHaveTenant interface</h5>
			<p>We may need to share an <strong>entity type</strong> between host and tenants. So, an entity 
may be owned by a tenant or the host. IMayHaveTenant interface also defines 
				<strong>TenantId</strong> (similar to IMustHaveTenant), but <strong>nullable</strong> in this case. An example 
entitiy that implements IMayHaveTenant:</p>
			<pre lang="cs">public class Role : Entity, <strong>IMayHaveTenant</strong>
{
    <strong>public int? TenantId { get; set; }</strong>

    public string RoleName { get; set; }

    //...other properties
}</pre>
			<p>We may use same Role class to store Host roles and Tenant roles. In this 
case, TenantId property says if this is an host entity or tenant entitiy. A 
				<strong>null</strong> value means this is a <strong>host</strong> entity, a 
				<strong>non-null</strong> value means this entity owned by a <strong>tenant</strong> which's Id is the 
				<strong>TenantId</strong>.</p>
			<p>IMayHaveTenant is not common as IMustHaveTenant. For example, a Product class 
can not be IMayHaveTenant since a Product is related to actual application 
functionality, not related to managing tenants. So, use IMayHaveTenant interface 
carefully since it's harder to maintain a code shared by host and tenants.</p>
			<h4>Saving Entities</h4>
			<p>A tenant user should not create/edit other tenant entities. ASP.NET 
Boilerplate checks it on saving changes to database if related data filters are 
enabled.&nbsp;</p>
			<p>See <a href="/Pages/Documents/Data-Filters">data filters</a> document for 
more information on data filters.</p>

		</div>

	</body>

</html>
